home *** CD-ROM | disk | FTP | other *** search
- /* test sortlist */
-
- #include <stdlib.h>
- #include <stdio.h>
-
- #include "sortlist.h"
- #include "slintrnl.h"
-
- typedef unsigned int UINT;
-
- #define MAX_ELEM_WORDS 50
- UINT elem_words;
-
- #define MAX_LIST 2000
- char in[MAX_LIST];
- UINT max_elems;
-
- UINT min_num_elems[30];
-
- int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0;
- UINT u1 = 0, u2 = 0, u3 = 0, u4 = 0, u5 = 0, u6 = 0, u7 = 0, u8 = 0, u9 = 0;
-
- void chk(int cond, char *msg)
- {
- if (cond)
- return;
-
- printf("ERROR: %s\n", msg);
- printf("i1=%d i2=%d i3=%d i4=%d i5=%d\n", i1, i2, i3, i4, i5);
- printf("u1=%u u2=%u u3=%u u4=%u u5=%u u6=%u\n", u1, u2, u3, u4, u5, u6);
- printf("u7=%u u8=%u u9=%u\n", u7, u8, u9);
-
- exit(1);
- }
-
- void set_elem(UINT *elem, UINT val)
- {
- UINT i;
-
- for (i = 0; i < elem_words; i++)
- elem[i] = val + i;
-
- return;
- }
-
- void check_elem(const UINT *elem)
- {
- for (u7 = 1; u7 < elem_words; u7++)
- {
- u8 = elem[0] + u7;
- u9 = elem[u7];
- chk(u8 == u9, "corrupt element");
- }
-
- return;
- }
-
- typedef struct
- {
- int depth;
- UINT num_elems;
- }
- TREE_INFO;
-
- void check_subtree(void *tree, TREE_INFO *info)
- {
- if (!tree)
- {
- info->depth = 0;
- info->num_elems = 0;
- }
- else
- {
- TREE_INFO l, g;
- int bal = NODE(tree)->balance;
- UINT val = ((UINT *) ELEM_IN_NODE(tree))[0];
-
- check_subtree(NODE(tree)->branch[LESS_BRANCH], &l);
- check_subtree(NODE(tree)->branch[GREATER_BRANCH], &g);
-
- if (bal != (g.depth - l.depth))
- {
- printf("bad balance: val=%d bal=%d l=%d g=%d\n",
- val, bal, l.depth, g.depth);
- exit(1);
- }
-
- info->depth = (l.depth > g.depth ? l.depth : g.depth) + 1;
- info->num_elems = l.num_elems + g.num_elems + 1;
-
- if (info->num_elems < min_num_elems[info->depth])
- {
- printf("bad size: val=%u depth=%d num elems=%u min elems=%u\n",
- val, info->depth, info->num_elems,
- min_num_elems[info->depth]);
- exit(1);
- }
- }
- return;
- }
-
- void check_tree(SORT_LIST *sl, char *msg)
- {
- TREE_INFO i;
- check_subtree(sl->tree, &i);
-
- printf("%s: depth=%d num elems=%d\n", msg, i.depth, i.num_elems);
-
- return;
- }
-
- void add_elems(SORT_LIST *sl, UINT start_index, UINT count, UINT step)
- {
- UINT e[MAX_ELEM_WORDS];
- SL_RESULT r;
-
- u1 = start_index;
- u2 = step;
-
- while (count--)
- {
- set_elem(e, 2 * u1 + 1);
-
- if (!(in[u1]))
- {
- r = add_sort_list(sl, (void *) e);
- chk(r != SL_MEM_ALLOC_FAIL, "mem. allocation failure");
- chk(r == SL_SUCCESS, "said dup. key, but none");
- in[u1] = 1;
- }
- chk(SL_SUCCESS != add_sort_list(sl, (void *) e),
- "allowed dup. key");
-
- u1 += u2;
- u1 %= max_elems;
- }
-
- return;
- }
-
- void del_elems(SORT_LIST *sl, UINT start_index, UINT count, UINT step)
- {
- UINT e[MAX_ELEM_WORDS],val;
-
- u1 = start_index;
- u2 = step;
-
- while (count--)
- {
- val = 2 * u1 + 1;
- if (in[u1])
- {
- chk(SL_SUCCESS == delete_sort_list(sl, (void *) &val, (void *) e),
- "del. said no match when is");
- check_elem(e);
- u3 = ((UINT *) e)[0];
- chk(u3 == val, "del. wrong element");
- in[u1] = 0;
- }
- chk(SL_NO_MATCH == delete_sort_list(sl, (void *) &val, (void *) e),
- "del. said match when none");
-
- u1 += u2;
- u1 %= max_elems;
- }
-
- return;
- }
-
- int next_elem(void *elem, void *idx)
- {
- #define INDEX (*((UINT *) idx))
-
- if (INDEX == 666)
- return(1);
-
- set_elem(elem, 2 * INDEX + 1);
- in[INDEX] = 1;
- INDEX++;
-
- return(0);
- }
-
- int e_e_compare(const void *e1, const void *e2)
- {
- #define E1 ((const UINT *) e1)
- #define E2 ((const UINT *) e2)
-
- check_elem(E1);
- check_elem(E2);
-
- return(((int) *E1) - ((int) *E2));
- }
-
- int k_e_compare(const void *k, const void *e)
- {
- #define K ((const UINT *) k)
- #define E ((const UINT *) e)
-
- check_elem(E);
-
- return(((int) *K) - ((int) *E));
- }
-
- void do_find(SORT_LIST *sl, UINT match_type, UINT try, UINT should_find)
- {
- UINT *f;
-
- u1 = match_type;
- u2 = try;
- u3 = should_find;
-
- f = (UINT *) find_sort_list(sl, u1, (void *) &u2);
- if (u3)
- {
- chk(!!f, "nothing found");
- check_elem(f);
- u4 = ((UINT *) f)[0];
- chk(u4 == u3, "wrong element found");
- }
- else
- {
- if (f)
- u4 = ((UINT *) f)[0];
- chk(!f, "find should have failed");
- }
- return;
- }
-
- /* test tree with at least 1 element */
- void test_find(SORT_LIST *sl)
- {
- UINT i, j, last = 0;
-
- for (i = 0; !in[i]; i++)
- ;
- do_find(sl, MATCH_LEAST, 0, 2 * i + 1);
- for (i = max_elems - 1; !in[i]; i--)
- ;
- do_find(sl, MATCH_GREATEST, 0, 2 * i + 1);
-
-
- for (i = 0; i < max_elems; i++)
- {
- if (in[i])
- {
- j = 2 * i;
-
- do_find(sl, MATCH_EQUAL, j, 0);
- do_find(sl, MATCH_GREATER, j, j + 1);
- do_find(sl, MATCH_GREATER_EQUAL, j, j + 1);
-
- j++;
-
- do_find(sl, MATCH_EQUAL, j, j);
- do_find(sl, MATCH_GREATER_EQUAL, j, j);
- do_find(sl, MATCH_LESS_EQUAL, j, j);
- if (last)
- {
- do_find(sl, MATCH_GREATER, last, j);
- do_find(sl, MATCH_LESS, j, last);
- }
- last = j;
-
- j++;
-
- do_find(sl, MATCH_EQUAL, j, 0);
- do_find(sl, MATCH_LESS, j, j - 1);
- do_find(sl, MATCH_LESS_EQUAL, j, j - 1);
- }
-
- }
-
- return;
- }
-
- void test_find_empty(SORT_LIST *sl)
- {
- int val = max_elems + 1;
- do_find(sl, MATCH_LEAST, 0, 0);
- do_find(sl, MATCH_GREATEST, 0, 0);
- do_find(sl, MATCH_EQUAL, val, 0);
- do_find(sl, MATCH_GREATER, val, 0);
- do_find(sl, MATCH_GREATER_EQUAL, val, 0);
- do_find(sl, MATCH_LESS, val, 0);
- do_find(sl, MATCH_LESS_EQUAL, val, 0);
- return;
- }
-
- /* for apply test:
- u1 - forward flag
- u2 - start bound
- u3 - end bound
- u4 - index of next apply element
- u5 - end seen flag
- */
-
- void next_apply(void)
- {
- do
- {
- if (u1)
- {
- if (u4 == max_elems)
- return;
- u4++;
- }
- else
- {
- if (u4 == 0)
- {
- u4 = max_elems;
- return;
- }
- u4--;
- }
- }
- while (!in[u4]);
-
- return;
- }
-
- char param_string[] = "second apply param";
-
- int apply_func(void *elem, void *param)
- {
- chk(!u5, "apply past end bound");
- chk(u4 < max_elems, "apply should have stopped");
-
- chk(param == (void *) param_string, "bad param. apply");
- check_elem(elem);
- if (u1)
- u5 = u3 < (2 * u4 + 1);
- else
- u5 = u2 > (2 * u4 + 1);
- if (!u5)
- {
- u6 = ((UINT *) elem)[0];
- chk (u6 == (2 * u4 + 1), "apply wrong order");
- next_apply();
- }
-
- return(u5);
- }
-
- /* at least 1 element */
- void test_apply(SORT_LIST *sl)
- {
- UINT bottom_index, top_index;
-
- for (bottom_index = 0; !in[bottom_index]; bottom_index++)
- ;
-
- u1 = 1;
- u3 = 2 * (max_elems + 1);
- u4 = bottom_index;
- u5 = 0;
- chk(apply_sort_list(sl, apply_func, (void *) param_string, u1,
- (void *) 0) == 0, "bad apply no start");
-
- for (top_index = max_elems - 1; !in[top_index]; top_index--)
- ;
- for ( ; ; )
- {
- u2 = 2 * bottom_index;
- u3 = 2 * (top_index + 1);
- u1 = 1;
- u4 = bottom_index;
- u5 = 0;
- chk(apply_sort_list(sl, apply_func, (void *) param_string, u1,
- (void *) &u2) == (u4 != max_elems),
- "bad apply w/start");
- u1 = 0;
- u4 = top_index;
- u5 = 0;
- chk(apply_sort_list(sl, apply_func, (void *) param_string, u1,
- (void *) &u3) == (u4 != max_elems),
- "bad apply w/start");
- u2++;
- u3--;
- u1 = 1;
- u4 = bottom_index;
- u5 = 0;
- chk(apply_sort_list(sl, apply_func, (void *) param_string, u1,
- (void *) &u2) == (u4 != max_elems),
- "bad apply w/start");
- u1 = 0;
- u4 = top_index;
- u5 = 0;
- chk(apply_sort_list(sl, apply_func, (void *) param_string, u1,
- (void *) &u3) == (u4 != max_elems),
- "bad apply w/start");
-
- if (bottom_index == top_index)
- break;
-
- do
- bottom_index++;
- while (!(in[bottom_index]));
- do
- top_index--;
- while (!(in[top_index]));
-
- if (bottom_index > top_index)
- break;
- }
- return;
- }
-
- void test_apply_empty(SORT_LIST *sl)
- {
- u5 = 1;
- chk(apply_sort_list(sl, apply_func, (void *) param_string, 1,
- (void *) &u3) == 0, "bad apply empty");
- chk(apply_sort_list(sl, apply_func, (void *) param_string, 0,
- (void *) &u3) == 0, "bad apply empty");
- return;
- }
-
- int main()
- {
- SORT_LIST sl;
- UINT i;
- SL_RESULT r;
-
- min_num_elems[0] = 0;
- min_num_elems[1] = 1;
- for (i = 2; i < 30; i++)
- min_num_elems[i] = min_num_elems[i - 1] + min_num_elems[i - 2] + 1;
-
- max_elems = 100;
- elem_words = 1;
-
- printf("max elems=%u elem words=%u\n", max_elems, elem_words);
-
- for (i = 0; i < max_elems; i++)
- in[i] = 0;
-
- init_sort_list(&sl, elem_words * sizeof(UINT), e_e_compare, k_e_compare);
- check_tree(&sl, "after init");
- test_find_empty(&sl);
- test_apply_empty(&sl);
-
- add_elems(&sl, 69, 1, 0);
-
- check_tree(&sl,"after add 1");
- test_find(&sl);
- test_apply(&sl);
-
- add_elems(&sl, 30, 90, 13);
-
- check_tree(&sl, "after add 2");
- test_find(&sl);
- test_apply(&sl);
-
- del_elems(&sl, 30, 90, 87);
-
- check_tree(&sl, "after del 1");
- test_find(&sl);
- test_apply(&sl);
-
- del_elems(&sl, 1, 100, 1);
-
- check_tree(&sl, "after del 2");
- test_find_empty(&sl);
- test_apply_empty(&sl);
-
- add_elems(&sl, 30, 100, 99);
-
- check_tree(&sl, "after add 3");
- test_find(&sl);
- test_apply(&sl);
-
- clear_sort_list(&sl);
-
- check_tree(&sl, "after clear");
- test_find_empty(&sl);
- test_apply_empty(&sl);
-
- max_elems = 2000;
- elem_words = 50;
-
- printf("max elems=%u elem words=%u\n", max_elems, elem_words);
-
- for (i = 0; i < max_elems; i++)
- in[i] = 0;
-
- init_sort_list(&sl, elem_words * sizeof(UINT), e_e_compare, k_e_compare);
-
- check_tree(&sl, "after init");
- test_find_empty(&sl);
- test_apply_empty(&sl);
-
- add_elems(&sl, 699, 1, 0);
-
- check_tree(&sl, "after add 1");
- test_find(&sl);
- test_apply(&sl);
-
- add_elems(&sl, 300, 1800, 13 * 13);
-
- check_tree(&sl, "after add 2");
- test_find(&sl);
-
- del_elems(&sl, 300, 1850, (2000 - 13 * 13));
-
- check_tree(&sl, "after del 1");
- test_find(&sl);
- test_apply(&sl);
-
- del_elems(&sl, 1, 2000, 1);
-
- check_tree(&sl, "after del 2");
- test_find_empty(&sl);
- test_apply_empty(&sl);
-
- add_elems(&sl, 300, 2000, 999);
-
- check_tree(&sl, "after add 3");
- test_find(&sl);
-
- clear_sort_list(&sl);
-
- check_tree(&sl, "after clear");
- test_find_empty(&sl);
- test_apply_empty(&sl);
-
- for (i = 0; i < max_elems; i++)
- in[i] = 0;
-
- i = 0;
- chk(build_sort_list(&sl, 500, next_elem, (void *) &i) == SL_SUCCESS,
- "bad build");
-
- check_tree(&sl, "after build");
- test_find(&sl);
- chk(i == 500, "i should be 500");
-
- clear_sort_list(&sl);
-
- i = 500;
- chk(build_sort_list(&sl, 200, next_elem, (void *) &i) == SL_ABORT,
- "build should have aborted");
- check_tree(&sl, "after bad build");
- test_find_empty(&sl);
- chk(i == 666, "i should be 666");
-
- printf("SUCCESS!\n");
-
- return(0);
- }
-